﻿using CefSharp;
using CefSharp.WinForms;
using Newtonsoft.Json;
using Spire.Pdf;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using static 千牛批量开票助手.Func.Cookies;
using static 千牛批量开票助手.Func.Configs;
using System.Data;
using static 千牛批量开票助手.Func.Hooks;

namespace 千牛批量开票助手.Func
{
    internal class Threads
    {
        public static List<Cookie> COOKIES;
        public static bool LOGIN_STATUS = false;           // 登录状态
        public static bool RUN_STATUS = false;             // 主线程执行状态, 主要用于全局控制
        public static bool DATA_LOCK = false;              // 线程间数据锁状态, 主要用于避免线程间的数据执行冲突
        public static bool IDENTIFY_STATUS = false;        // 淘宝验证对话框弹出状态
        public static string OL_ORDER_NUM = string.Empty;

        public class LoginCls
        {
            public bool FAutoLogin { get; set; }
            public Form FMainForm { get; set; }
            public ComboBox FCboStatus { get; set; }
            public GroupBox FGrpUsr {  get; set; }
            public DataGridView FDgvList { get; set; }
            public NumericUpDown FNudLoopTime { get; set; }
            public NumericUpDown FNudLoopQty { get; set; }
            public CheckBox FChbRunStatus { get; set; }
            public CheckBox FChbDataLock { get; set; }
            public CheckBox FChbIdentifyStatus { get; set; }
            public TextBox FTxtInvoicePath { get; set; }
            public TextBox FTxtBackupPath { get; set; }
            public Button FBtnRun { get; set; }
            public Label FLblListCount { get; set; }
            public ChromiumWebBrowser FWebL { get; set; }
            public ChromiumWebBrowser FWebR { get; set; }

            public TextBox FTxtUsr { get; set; }
            public TextBox FTxtPwd { get; set; }
            public SplitContainer FSplWeb { get; set; }
        }

        public class InvoiceCls
        {
            public int FSeq { get; set; }
            public string FOrderNum { get; set; }
            public List<string> FPaths { get; set; }
            public double FAmount { get; set; }
            public List<string> FAmountDetail{ get; set; }
        }

        /// <summary>
        /// 多线程 - 确认登录状态
        /// </summary>
        public static void Thread_CheckLoginAndJSAdd(object loginCls)
        {
            // 等待 0.1 秒, 避免页面还没开始跳转
            Thread.Sleep(100);

            LoginCls __loginCls__ = loginCls as LoginCls;
            
            // 网页加载等待 10 秒, 超时则结束加载
            double i = 0;
            while (i < 10)
            {
                if (!__loginCls__.FWebL.IsLoading) break;
                i += 0.1;
                Thread.Sleep(100);
            }

            if (i >= 10)
            {
                __loginCls__.FMainForm.Invoke(new Action(() => { __loginCls__.FGrpUsr.Enabled = true; }));
                MessageBox.Show("登录页面加载失败, 请重新操作", "淘宝登录异常", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            // 扫码登录状态为 False
            if (__loginCls__.FAutoLogin)
            {
                // 注入 js 脚本
                string js = @"
                    const InputLoginInfo = async (usr, pwd) => {
                        const sleep = (delay) => new Promise((resolve) => setTimeout(resolve, delay));
                        document.getElementById('fm-login-id').value = usr;
                        document.getElementById('fm-login-password').value = pwd;
                        await sleep(200);
                        document.getElementsByClassName('password-login')[0].click();
                    };
                ";
                js += $"InputLoginInfo('{__loginCls__.FTxtUsr.Text}', '{__loginCls__.FTxtPwd.Text}');";
                __loginCls__.FWebL.ExecuteScriptAsync(js);
            }

            // 执行登录之前读取上次登录的 Cookies
            Uri uri = new Uri(__loginCls__.FWebL.Address);
            ICookieManager cookieManager = __loginCls__.FWebL.GetCookieManager();

            COOKIES = ReadCookies();
            if (COOKIES != null) { foreach (Cookie item in COOKIES) cookieManager.SetCookieAsync(uri.Host, item); }

            // 启动等待登录线程, 淘宝登录可能需要用到验证码及手动滑动验证, 需要等待人工输入
            LOGIN_STATUS = true;
            Thread thread = new Thread(Thread_Login);
            thread.Start(__loginCls__);
        }

        /// <summary>
        /// 多线程 - 执行淘宝登录
        /// </summary>
        public static void Thread_Login(object loginCls)
        {
            LoginCls __loginCls__ = loginCls as LoginCls;

            // 等待登录完成, 默认等待 2 分钟, 超时则结束加载 
            double i = 0;
            while (i < 120)
            {
                if (!LOGIN_STATUS) return;
                if (__loginCls__.FWebL.Address.ToLower().Contains("myseller.taobao.com/home")) break;

                i += 0.1;
                Thread.Sleep(100);
            }

            if (i >= 120)
            {
                __loginCls__.FMainForm.Invoke(new Action(() => { __loginCls__.FGrpUsr.Enabled = true; }));
                MessageBox.Show("登录超时, 请重新登录", "淘宝登录异常", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            /** 登录成功, 读取当前浏览器 Cookies, 并设置给右边的浏览器 **/
            // 读取当前浏览器 Cookies
            COOKIES = new List<Cookie>();
            CookieVisitor cookieVisitor = new CookieVisitor();
            cookieVisitor.SendCookie += Visitor_SendCookie;
            ICookieManager cookieManager = __loginCls__.FWebL.GetCookieManager();
            cookieManager.VisitAllCookies(cookieVisitor);

            // 在右侧浏览器中载入左侧 Cookies
            Uri uri = new Uri(__loginCls__.FWebL.Address);
            cookieManager = __loginCls__.FWebR.GetCookieManager();
            foreach (Cookie item in COOKIES) cookieManager.SetCookieAsync(uri.Host, item);

            // 保留 Cookies 到本地
            SaveCookies(COOKIES);

            // 加载登录成功页
            __loginCls__.FWebR.Load(__loginCls__.FWebL.Address);
            __loginCls__.FMainForm.Invoke(new Action(() => { __loginCls__.FSplWeb.Panel2Collapsed = false; }));

            // 检查页面是否完成登录跳转
            Thread.Sleep(200);

            i = 0;
            while (i < 120)
            {
                if (!LOGIN_STATUS) return;
                if (!__loginCls__.FWebL.IsLoading & !__loginCls__.FWebR.IsLoading) break;
                i += 0.1;
                Thread.Sleep(100);
            }

            if (i >= 120)
            {
                __loginCls__.FMainForm.Invoke(new Action(() => { __loginCls__.FGrpUsr.Enabled = true; }));
                MessageBox.Show("登录异常, 请重新登录", "淘宝登录异常", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            /** 登录成功, 分别跳转发票界面 **/
            __loginCls__.FWebL.Load("https://einvoice.taobao.com/#/online/invoice/apply");
            __loginCls__.FWebR.Load("https://einvoice.taobao.com/#/online/invoice/pending");

            // 检查页面是否完成登录跳转
            Thread.Sleep(200);

            i = 0;
            while (i < 120)
            {
                if (!LOGIN_STATUS) return;
                if (!__loginCls__.FWebL.IsLoading & !__loginCls__.FWebR.IsLoading) break;
                i += 0.1;
                Thread.Sleep(100);
            }

            if (i >= 120)
            {
                __loginCls__.FMainForm.Invoke(new Action(() => { __loginCls__.FGrpUsr.Enabled = true; }));
                MessageBox.Show("登录异常, 请重新登录", "淘宝登录异常", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            // 反写执行结果至界面
            __loginCls__.FMainForm.Invoke(new Action(() => {
                __loginCls__.FCboStatus.Text = "已登录";
                __loginCls__.FGrpUsr.Enabled = true;
            }));

            LOGIN_STATUS = false;
        }

        public static void AddJS(LoginCls loginCls)
        {
            string js = GlobalJS();

            loginCls.FWebL.ExecuteScriptAsync(js);
            loginCls.FWebR.ExecuteScriptAsync(js);
        }

        private static void Visitor_SendCookie(Cookie cookie)
        {
            COOKIES.Add(cookie);
        }

        /// <summary>
        /// 多线程 - 读取发票 PDF
        /// </summary>
        [Obsolete]
        public static void Thread_ReadPDF(object loginCls)
        {
            LoginCls __loginCls__ = loginCls as LoginCls;

            while (true)
            {
                if (!RUN_STATUS) return;

                if (!DATA_LOCK)
                {
                    DATA_LOCK = true;

                    // ------------------------------------ 删除已处理完成的发票 PDF 文件 ------------------------------------
                    // 备份已完成的发票 PDF 文件至备份文件夹, 并从列表中删除记录
                    int deleteCount = 0;
                    foreach (DataGridViewRow item in __loginCls__.FDgvList.Rows) { if ((new string[] { "已完成", "无需上传" }).Contains(Convert.ToString(item.Cells["FStatus"].Value))) deleteCount++; }
                    
                    while (deleteCount > 0)
                    {
                        for (int i = 0; i < __loginCls__.FDgvList.Rows.Count; i++)
                        {
                            DataGridViewRow item = __loginCls__.FDgvList.Rows[i];
                            if ((new string[] { "已完成", "无需上传" }).Contains(Convert.ToString(item.Cells["FStatus"].Value)))
                            {
                                string[] paths = Convert.ToString(item.Cells["FPath"].Value).Split(';');
                                foreach (string path in paths)
                                {
                                    if (File.Exists(path))
                                    {
                                        string bkPath = $"{__loginCls__.FTxtBackupPath.Text}\\{Path.GetFileName(path)}";
                                        if (File.Exists(bkPath)) File.Delete(path);
                                        File.Move(path, bkPath);
                                    }
                                }
                                __loginCls__.FMainForm.Invoke(new Action(() => { __loginCls__.FDgvList.Rows.RemoveAt(i); }));

                                deleteCount--;
                                break;
                            }
                        }
                    }

                    // ----------------------------------------- 读取发票 PDF 文件 ------------------------------------------
                    Dictionary<string, InvoiceCls> dictInvoice = new Dictionary<string, InvoiceCls>();
                    List<string> pathList = new List<string>();

                    foreach (DataGridViewRow item in __loginCls__.FDgvList.Rows)
                    {
                        string orderNum = Convert.ToString(item.Cells["FOrderNum"].Value);
                        List<string> paths = (from x in Convert.ToString(item.Cells["FPath"].Value).Split(';') select x).ToList();
                        double amount = Convert.ToDouble(item.Cells["FAmount"].Value);

                        pathList.AddRange(paths);
                        if (!dictInvoice.ContainsKey(orderNum)) dictInvoice.Add(orderNum, new InvoiceCls { FSeq = item.Index, FOrderNum = orderNum, FPaths = paths, FAmount = amount, FAmountDetail = new List<string> { amount.ToString("F2") } });
                    }

                    // 读取指定文件夹中的 PDF 文件数量
                    string[] files = Directory.GetFiles(__loginCls__.FTxtInvoicePath.Text, "*.pdf");

                    // 读取 PDF 的时间在整个流程里比较长, 因此需要多批次轮询, 以提高整体流程效率
                    // 轮询批次以人工调整为准, 最低一次轮询文件个数为 10, 最高 100
                    int j = 0;
                    for (int i = 0; i < files.Length; i++)
                    {
                        if (!RUN_STATUS) return;
                        if (j > __loginCls__.FNudLoopQty.Value) break;

                        string item = files[i];

                        // 当前执行列表以及备份文件夹中同时不存在的才能执行, 避免重复操作
                        if (!pathList.Contains(item) & !File.Exists($"{__loginCls__.FTxtBackupPath.Text}\\{Path.GetFileName(item)}"))
                        {
                            PdfDocument pdf = new PdfDocument();
                            pdf.LoadFromFile(item);

                            string content = pdf.Pages[0].ExtractText();

                            Regex regexOrderNum = new Regex(@"备[ ]+(\d+)[\r\n]");
                            Regex regexAmount = new Regex(@"\*.*?\*.*?(\d+\.\d{1,2})[ ]+\d+%[ ]+(\d+\.\d{1,2})[\r\n]");

                            if (!regexOrderNum.IsMatch(content)) continue;
                            if (!regexAmount.IsMatch(content)) continue;

                            // 读取发票备注里的订单编号
                            string orderNum = regexOrderNum.Match(content).Groups[1].Value;

                            // 读取发票备注中的明细
                            MatchCollection matchs = regexAmount.Matches(content);
                            double total = 0;
                            foreach (Match match in matchs)
                            {
                                double amount = Convert.ToDouble(match.Groups[1].Value);
                                double tax = Convert.ToDouble(match.Groups[2].Value);
                                total += amount + tax;
                            }

                            if (dictInvoice.ContainsKey(orderNum))
                            {
                                InvoiceCls invoiceCls = dictInvoice[orderNum];
                                if (invoiceCls.FPaths.Contains(item)) continue;
                                invoiceCls.FPaths.Add(item);
                                invoiceCls.FAmountDetail.Add(total.ToString("F2"));

                                dictInvoice[orderNum].FAmount += total;

                                // 更新任务列表
                                __loginCls__.FMainForm.Invoke(new Action(() => {
                                    DataGridViewRow rowItem = __loginCls__.FDgvList.Rows[dictInvoice[orderNum].FSeq];
                                    rowItem.Cells["FQty"].Value = invoiceCls.FPaths.Count;
                                    rowItem.Cells["FAmount"].Value = invoiceCls.FAmount;
                                    rowItem.Cells["FPath"].Value = string.Join(";", invoiceCls.FPaths);
                                    rowItem.Cells["FAmountDetail"].Value = string.Join(";", invoiceCls.FAmountDetail);
                                    rowItem.Cells["FStatus"].Value = "待处理";
                                }));
                            }
                            else
                            {
                                __loginCls__.FMainForm.Invoke(new Action(() => { __loginCls__.FDgvList.Rows.Add("待处理", "1", orderNum, item, total, 0); }));
                                dictInvoice.Add(orderNum, new InvoiceCls {
                                    FSeq = __loginCls__.FDgvList.Rows.Count - 1,
                                    FOrderNum = orderNum,
                                    FPaths = new List<string> { item },
                                    FAmount = total,
                                    FAmountDetail = new List<string> { total.ToString("F2") }
                                });
                            }

                            j++;
                        }
                    }

                    DATA_LOCK = false;
                }

                // 轮询时间由人工来控制, 固定最短为 10 秒, 最长为 100 秒
                Thread.Sleep(Convert.ToInt32(__loginCls__.FNudLoopTime.Value * 1000));
            }
        }

        public static void Thread_IdentifyCheck(object loginCls)
        {
            LoginCls __loginCls__ = loginCls as LoginCls;

            while (true)
            {
                if (!RUN_STATUS) return;

                // 每次循环都识别一次是否有弹出检验对话框, 如果有则暂停执行
                Task<JavascriptResponse> webLTask = __loginCls__.FWebL.EvaluateScriptAsync($"GetIdentifyCheck();");
                Task<JavascriptResponse> webRTask = __loginCls__.FWebR.EvaluateScriptAsync($"GetIdentifyCheck();");

                if (webLTask.Result.Result != null & webRTask.Result.Result != null)
                {
                    IDENTIFY_STATUS = (
                        webLTask.Result.Result.ToString().ToLower() == "false" ||
                        webRTask.Result.Result.ToString().ToLower() == "false"
                    );

                    if (IDENTIFY_STATUS)
                    {
                        __loginCls__.FMainForm.Invoke(new Action(() => {
                            __loginCls__.FBtnRun.Enabled = true;
                            __loginCls__.FBtnRun.Text = "恢复运行\r\n(Ctrl + F5)";
                        }));
                    } else
                    {
                        __loginCls__.FMainForm.Invoke(new Action(() => {
                            __loginCls__.FBtnRun.Enabled = false;
                            __loginCls__.FBtnRun.Text = "运行中...";
                        }));
                    }
                }

                __loginCls__.FMainForm.Invoke(new Action(() =>
                {
                    __loginCls__.FLblListCount.Text = $"列表总数：{__loginCls__.FDgvList.Rows.Count}";
                    __loginCls__.FChbRunStatus.Checked = RUN_STATUS;
                    __loginCls__.FChbDataLock.Checked = DATA_LOCK;
                    __loginCls__.FChbIdentifyStatus.Checked = IDENTIFY_STATUS;
                }));

                // 每 0.2 秒检测一次
                Thread.Sleep(200);
            }   
        }

        /// <summary>
        /// 多线程 - 批量点击统计开票
        /// </summary>
        public static void Thread_ClickAllow(object loginCls)
        {
            LoginCls __loginCls__ = loginCls as LoginCls;

            Random random = new Random();

            while (true)
            {
                if (!RUN_STATUS) return;

                // 单次循环只执行一条
                if (!DATA_LOCK & !IDENTIFY_STATUS)
                {
                    // 启动执行时, 避开其他线程操作, 避免操作数据冲突
                    for (int i = 0; i < __loginCls__.FDgvList.Rows.Count; i++)
                    {
                        DataGridViewRow row = __loginCls__.FDgvList.Rows[i];
                        if (Convert.ToString(row.Cells["FStatus"].Value) == "待处理")
                        {
                            __loginCls__.FWebL.EvaluateScriptAsync($"InputOrderNum('{Convert.ToString(row.Cells["FOrderNum"].Value)}');");
                            
                            // 随机等待 0.5-1.0 秒, 避免反爬检测
                            Thread.Sleep(random.Next(500, 1000));

                            Task<JavascriptResponse> webRTask = __loginCls__.FWebL.EvaluateScriptAsync($"GetSearchCount()");

                            if (DATA_LOCK || IDENTIFY_STATUS) break;

                            if (webRTask.Result.Result != null)
                            {
                                if (Convert.ToInt32(webRTask.Result.Result.ToString()) > 0)
                                {
                                    // 随机等待 0.5-1.0 秒, 避免反爬检测
                                    Thread.Sleep(random.Next(500, 1000));

                                    if (DATA_LOCK || IDENTIFY_STATUS) break;

                                    // 执行点击事件时, 避免其他线程影响
                                    DATA_LOCK = true;

                                    // 调用鼠标, 使左边浏览器获取焦点
                                    SetWebObjFocus(__loginCls__.FMainForm, __loginCls__.FWebR);
                                    Thread.Sleep(100);

                                    string rs = __loginCls__.FWebL.EvaluateScriptAsync($"ClickAllow({row.Cells["FAmount"].Value})").Result.Result.ToString();
                                    Dictionary<string, object> dictRs = JsonConvert.DeserializeObject<Dictionary<string, object>>(rs);

                                    if (Convert.ToBoolean(dictRs["status"]))
                                    {
                                        row.Cells["FOLAmount"].Value = Convert.ToDouble(dictRs["amount"]);
                                        row.Cells["FStatus"].Value = Convert.ToDecimal(row.Cells["FOLAmount"].Value) == Convert.ToDecimal(row.Cells["FAmount"].Value) ? "待上传" : null;
                                    }
                                    else
                                    {
                                        row.Cells["FStatus"].Value = "无需上传";
                                    }

                                    // 解除其他线程影响
                                    DATA_LOCK = false;
                                } else
                                {
                                    row.Cells["FStatus"].Value = "待上传";
                                }
                                // 2024-04-14 21:57 Yogurt_cry: 如果后续出现因网络问题导致点击 [同意] 后, 平台状态没有更新而出现漏上传的情况, 建议在此处新增一层判断, 用于检测点击 [同意] 后的状态
                                // 本次没有增加的原因主要考虑到执行的效率, 以及考虑公司环境的网络稳定性。
                            }
                            break;
                        }
                    }
                }

                // 随机等待 0.5-1.0 秒, 避免反爬检测
                Thread.Sleep(random.Next(500, 1000));
            }
        }

        /// <summary>
        /// 多线程 - 批量上传发票
        /// </summary>
        public static void Thread_Upload(object loginCls)
        {
            LoginCls __loginCls__ = loginCls as LoginCls;

            Random random = new Random();
            while (true)
            {
                if (!RUN_STATUS) return;

                // 单次循环只执行一条
                if (!DATA_LOCK & !IDENTIFY_STATUS)
                {
                    // 启动执行时, 避开其他线程操作, 避免操作数据冲突
                    for (int i = 0; i < __loginCls__.FDgvList.Rows.Count; i++)
                    {
                        DataGridViewRow row = __loginCls__.FDgvList.Rows[i];
                        if (Convert.ToString(row.Cells["FStatus"].Value) == "待上传")
                        {
                            __loginCls__.FWebR.EvaluateScriptAsync($"InputOrderNum('{Convert.ToString(row.Cells["FOrderNum"].Value)}');");

                            // 随机等待 0.5-1.0 秒, 避免反爬检测
                            Thread.Sleep(random.Next(500, 1000));

                            Task<JavascriptResponse> webRTask = __loginCls__.FWebR.EvaluateScriptAsync($"GetSearchCount()");

                            if (webRTask.Result.Result != null)
                            {
                                if (DATA_LOCK || IDENTIFY_STATUS) break;

                                if (Convert.ToInt32(webRTask.Result.Result.ToString()) > 0)
                                {
                                    if (DATA_LOCK || IDENTIFY_STATUS) break;

                                    // 执行上传过程中暂停其他线程执行操作
                                    DATA_LOCK = true;

                                    // 随机等待 0.5-1.0 秒, 避免反爬检测
                                    Thread.Sleep(random.Next(500, 1000));
                                    // 根据发票数量上传多个文件
                                    __loginCls__.FWebR.EvaluateScriptAsync($"ClickInput({row.Cells["FQty"].Value})");

                                    string[] paths = Convert.ToString(row.Cells["FPath"].Value).Split(';');
                                    string[] amounts = Convert.ToString(row.Cells["FAmountDetail"].Value).Split(';');

                                    // 执行上传操作
                                    int flag = 0;
                                    int totalQty = Convert.ToInt32(row.Cells["FQty"].Value);
                                    for (int j = 0; j < totalQty; j++)
                                    {
                                        SetWebObjFocus(__loginCls__.FMainForm, __loginCls__.FWebR);
                                        Thread.Sleep(100);

                                        __loginCls__.FWebR.EvaluateScriptAsync($"UploadClick({j});");

                                        // 等待 1.0 秒上传对话框打开
                                        Thread.Sleep(1000);

                                        // 执行上传句柄
                                        if (DialogUploadSingleFile(paths[j])) flag++;

                                        // 随机等待 0.5-1.0 秒, 避免反爬检测
                                        Thread.Sleep(random.Next(500, 1000));

                                        // 更新发票金额
                                        Task<JavascriptResponse> inputInvoiceTask = __loginCls__.FWebR.EvaluateScriptAsync($"InputInvoiceInfo({j}, {amounts[j]});");

                                        if (inputInvoiceTask.Result.Result == null)
                                        {
                                            flag--;
                                            break;
                                        }

                                        if (!Convert.ToBoolean(inputInvoiceTask.Result.Result.ToString()))
                                        {
                                            flag--;
                                            break;
                                        }

                                        // 随机等待 0.5-1.0 秒, 避免反爬检测
                                        Thread.Sleep(random.Next(500, 1000));
                                    }

                                    // 完成上传
                                    if (flag == totalQty)
                                    {
                                        __loginCls__.FWebR.EvaluateScriptAsync($"ClickDialogFinish()"); // [完成开票] 按钮
                                        row.Cells["FStatus"].Value = "已完成";
                                    }
                                    else
                                    {
                                        __loginCls__.FWebR.EvaluateScriptAsync($"ClickDialogClose()");  // 关闭对话框
                                        row.Cells["FStatus"].Value = "上传失败";
                                    }

                                    // 上传完毕后恢复其他线程执行操作
                                    DATA_LOCK = false;
                                }
                                else
                                {
                                    // 按照该流程走下去, 在待录入列表中没有找到发票的, 一致认定为[已完成]
                                    row.Cells["FStatus"].Value = "已完成";
                                }
                                // 2024-04-14 21:57 Yogurt_cry: 如果后续出现因网络问题导致点击 [同意] 后, 平台状态没有更新而出现漏上传的情况, 建议在此处新增一层判断, 用于检测点击 [同意] 后的状态
                                // 本次没有增加的原因主要考虑到执行的效率, 以及考虑公司环境的网络稳定性。
                            }

                            // 随机等待 0.5-1.0 秒, 避免反爬检测
                            Thread.Sleep(random.Next(500, 1000));
                            break;
                        }
                    }
                }

                // 随机等待 0.5-1.0 秒, 避免反爬检测
                Thread.Sleep(random.Next(500, 1000));
            }
        }
    }
}
